﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

namespace MJB.UI.ContentEditor
{
    /// <summary>
    /// This class holds extension methods that are used throughout the application.
    /// </summary>
    public static class ExtensionMethods
    {

        /// <summary>
        /// Displays the raw exception and only includes the message of the exception
        /// itself.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static Exception DisplayError(this Exception e)
        {
            StringBuilder errorBuilder = new StringBuilder();
            errorBuilder.Append("Error Type: ");
            errorBuilder.Append(e.GetType().Name);
            errorBuilder.Append(Environment.NewLine);

            errorBuilder.Append("Error Message: ");
            errorBuilder.Append(e.Message);
            errorBuilder.Append(Environment.NewLine);

            MessageBox.Show(Application.Current.MainWindow,
                errorBuilder.ToString(),
                "Error",
                MessageBoxButton.OK,
                MessageBoxImage.Error);

            return e;

        }

        /// <summary>
        /// Shows a message box that displays an error.
        /// </summary>
        /// <param name="e"></param>
        /// <param name="message"></param>
        public static Exception DisplayError(this Exception e, string message)
        {
            StringBuilder errorBuilder = new StringBuilder();
            errorBuilder.Append(message);
            errorBuilder.Append(Environment.NewLine);
            
            errorBuilder.Append("Error Type: ");
            errorBuilder.Append(e.GetType().Name);
            errorBuilder.Append(Environment.NewLine);

            errorBuilder.Append("Error Message: ");
            errorBuilder.Append(e.Message);
            errorBuilder.Append(Environment.NewLine);

            MessageBox.Show(Application.Current.MainWindow,
                errorBuilder.ToString(),
                "Error",
                MessageBoxButton.OK,
                MessageBoxImage.Error);

            return e;

        }

        /// <summary>
        /// Shows a message box that displays an error.
        /// </summary>
        /// <param name="e"></param>
        /// <param name="message"></param>
        public static Exception DisplayError(this Exception e, StringBuilder messageBuilder)
        {
            return ExtensionMethods.DisplayError(e, messageBuilder.ToString());
        }

        /// <summary>
        /// Displays a message dialog using the entered string and the current
        /// active window.
        /// </summary>                
        /// <param name="message">The string to display in the text of the dialog.</param>
        public static string DisplayMessageDialog(this string message)
        {
            MessageBox.Show(Application.Current.MainWindow,
                message,
                "Content Editor",
                MessageBoxButton.OK,
                MessageBoxImage.Information);

            return message;

        }

        /// <summary>
        /// Displays a dialog with a yes / no option and returns true if the user
        /// answers yes to the question.
        /// </summary>
        /// <param name="message">The string of the question to ask.</param>
        /// <returns>True if the user answers yes; otherwise, false.</returns>
        public static bool DisplayQuestionDialog(this string message)
        {
            MessageBoxResult result = MessageBox.Show(Application.Current.MainWindow,
                message,
                "Content Editor",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question);

            return (result == MessageBoxResult.Yes);

        }

        /// <summary>
        /// Displays a dialog with a yes / no option and returns true if the user 
        /// answers yes to the question.
        /// </summary>
        /// <param name="messageBuilder">The string builder that has the question.</param>
        /// <returns>True if the user answered yes, otherwise false.</returns>
        public static bool DisplayQuestionDialog(this StringBuilder messageBuilder)
        {
            return DisplayQuestionDialog(messageBuilder.ToString());
        }

        /// <summary>
        /// Defines a useful enumerator extension method.  Allows simple one-line 
        /// foreach statements using extension methods and lambda expressions.
        /// </summary>
        /// <typeparam name="T">The type to enumerate through.</typeparam>
        /// <param name="enumerable">The enumerator.</param>
        /// <param name="f">The function to call on each item in enumerable.</param>
        public static void ForEach<T>(this IEnumerable<T> enumerable, VoidFunc<T> f)
        {
            foreach(T t in enumerable)
            {
                f(t);
            }
        }

        /// <summary>
        /// Another useful method; iterates through each T in enumerable
        /// and calls a method that takes a T and returns an S.
        /// </summary>
        /// <typeparam name="T">The input type.</typeparam>
        /// <typeparam name="S">The output type.</typeparam>
        /// <param name="enumerable">The enumerable object.</param>
        /// <param name="f">The method to call.</param>
        /// <returns>An enumerator of type S.</returns>
        public static IEnumerable<S> ConvertTo<T, S>(this IEnumerable<T> enumerable, Func<T, S> f)
        {
            foreach(T t in enumerable)
            {
                yield return f(t);
            }
        }

    }

}
